<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">{{title}}</div>
    <script>
      const Vue = {
        createRenderer({ querySelector, insert }) {
          return {
            createApp(options) {
              return {
                mount(element) {
                  const parent = querySelector(element);
                  if (!options.render) {
                    options.render = this.compile(parent.innerHTML);
                  }
                  if (options.setup) {
                    this.setupState = options.setup();
                  }
                  if (options.data) {
                    this.data = options.data();
                  }
                  const proxy = new Proxy(this, {
                    get(target, key) {
                      if (target.setupState && key in target.setupState) {
                        return target.setupState[key];
                      } else {
                        return target.data[key];
                      }
                    },
                    set(target, key, val) {
                      if (target.setupState[key] && key in target.setupState) {
                        target.setupState[key] = val;
                      } else {
                        target.data[key] = val;
                      }
                    },
                  });
                  const el = options.render.call(proxy);
                  insert(el, parent)
                },
                compile(template) {
                  return function render() {
                    const h1 = document.createElement("h1");
                    h1.textContent = this.title;
                    return h1;
                  };
                },
              };
            },
          };
        },
        createApp(options) {
          const renderer = Vue.createRenderer({
            querySelector(sel) {
              return document.querySelector(sel);
            },
            insert(el, parent) {
              parent.innerHTML = "";
              parent.appendChild(el);
            }
          })
          return renderer.createApp(options)
        }
      };
    </script>
    <script>
      const app = Vue.createApp({
        data() {
          return {
            title: "hello vue3",
          };
        },
        setup() {
          return {
            title: "vue3, hello",
          };
        },
      });
      app.mount("#app");
    </script>
  </body>
</html>
